#include "QRSExpressionWidget.h"

#include "ExpressionManager.h"
#include "Core/MainWindow.h"
#include <QMessageBox>
#include "exprtk.hpp"

QRSExpressionWidget::QRSExpressionWidget(MainWindow* inMainWindow, QWidget* parent)
	: m_mainWindow(inMainWindow)
	, QWidget(parent)
	, ui(new Ui::QRSExpressionWidgetClass())
{
	ui->setupUi(this);

	m_expressionManager = m_mainWindow->GetExpressionManager();

	setAttribute(Qt::WA_DeleteOnClose);

	ui->expressionWidget->setColumnCount(4);
	// 设置水平表头标签
	QStringList headers;
	headers << "名称" << "公式" << "表达式值" << "具体内容";
	ui->expressionWidget->setHorizontalHeaderLabels(headers);

	// 设置表头样式
	ui->expressionWidget->horizontalHeader()->setStyleSheet(
		"QHeaderView::section{"
		"background-color: lightblue;"
		"color: black;"
		"border: 1px solid #6c6c6c;"
		"}"
	);

	// 设置 QTableWidget 的样式表以更改所有单元格的文本颜色
	ui->expressionWidget->setStyleSheet(
		"QTableWidget::item {"
		"color: black;"
		"}"
	);

	// 隐藏行计数
	ui->expressionWidget->verticalHeader()->setVisible(false);

	// 设置表格为不可编辑
	ui->expressionWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

	// 设置选择行为为选择整行
	ui->expressionWidget->setSelectionBehavior(QAbstractItemView::SelectRows);

	// 表达式表格内容初始化
	QList<std::shared_ptr<Expression>> expressions = m_expressionManager->GetValidExpressions();
	for (const auto& expression : expressions)
	{
		auto rowCount = ui->expressionWidget->rowCount();
		m_expressions.insert(rowCount, expression);
		ui->expressionWidget->insertRow(rowCount);
		ui->expressionWidget->setItem(rowCount, 0, new QTableWidgetItem(expression->GetTargetFeatureKey()));
		ui->expressionWidget->setItem(rowCount, 1, new QTableWidgetItem(expression->GetExpression()));
		ui->expressionWidget->setItem(rowCount, 2, new QTableWidgetItem(expression->GetValue()));
		ui->expressionWidget->setItem(rowCount, 3, new QTableWidgetItem(expression->GetTargetFeatureContent()));
	}

	// 设置默认选择行为
	if (m_expressions.size())
	{
		ui->expressionWidget->selectRow(0);
		onTableWidgetItemClicked(ui->expressionWidget->item(0, 0));
	}
	else
	{
		ui->key->setEnabled(false);
		ui->expression->setEnabled(false);
	}

    connect(ui->expressionWidget, &QTableWidget::itemClicked, this, &QRSExpressionWidget::onTableWidgetItemClicked);
    connect(ui->modifyButton, &QPushButton::clicked, this, &QRSExpressionWidget::onModifyExpression);
    connect(ui->addButton, &QPushButton::clicked, this, &QRSExpressionWidget::onAddExpression);
    connect(ui->deleteButton, &QPushButton::clicked, this, &QRSExpressionWidget::onDeleteExpression);
}

QRSExpressionWidget::~QRSExpressionWidget()
{
	delete ui;

	m_expressions.clear();
}

void QRSExpressionWidget::closeEvent(QCloseEvent* event)
{
	// 执行expression删除逻辑
	for (const auto& index : m_deleteExpressionIndex)
	{
		m_expressionManager->DeleteExpression(m_expressions[index]);
	}

	m_mainWindow->SubWidgetClose(bIsConfirmed);
}

void QRSExpressionWidget::onTableWidgetItemClicked(QTableWidgetItem* item)
{
	int row = item->row();
	m_selectedItem = { item->row() , item->column() };

	ui->key->setText(ui->expressionWidget->item(row, 0)->text());
	ui->expression->setText(ui->expressionWidget->item(row, 1)->text());

	bool bIsNativeExpression = m_expressions.value(m_selectedItem.first) ? m_expressions.value(m_selectedItem.first)->IsNativeExpression() : false;
	// 原生表达式不允许修改键
	ui->key->setEnabled(!bIsNativeExpression);
	// 原生表达式不允许删除
	ui->deleteButton->setEnabled(!bIsNativeExpression);
}

void QRSExpressionWidget::onModifyExpression()
{
    if (m_selectedItem.first < 0 || m_selectedItem.second < 0 || m_selectedItem.second > 3)
    {
        return;
    }

	if(m_expressions.contains(m_selectedItem.first))
	{
		auto expression = m_expressions.value(m_selectedItem.first);
		QList<std::shared_ptr<Feature>> associatedFeatures;
		if (!m_expressionManager->IsExpressionValid(ui->expression->text(), associatedFeatures))
		{
			QMessageBox::warning(this, "警告", "输入的公式无效");
			return;
		}
		// 对于自定义的表达式
		if (!expression->IsNativeExpression())
		{
			const std::shared_ptr<Feature> feature = m_expressionManager->GetFeature(ui->key->text());
			if (!feature)
			{
				QMessageBox::warning(this, "警告", "表达式修改的对象无效");
				return;
			}
			// 设置key
			expression->SetKey(feature);
			// 注册key
			m_expressionManager->CustomExpressionConfirmKey(expression);
			ui->expressionWidget->item(m_selectedItem.first, 0)->setText(ui->key->text());
		}

		// 创建一个ExprTK符号表，用来链接符号与参数
		exprtk::symbol_table<float> sym_table;
		for (const auto& feature : associatedFeatures)
		{
			sym_table.add_variable(feature->GetKey().toStdString(), feature->GetValue());
		}

		// 创建一个编译的表达式容器
		exprtk::expression<float> expr;
		expr.register_symbol_table(sym_table);  //使用符号表来注册一个表达式

		// 创建一个解析器，用于将string类型的表达式编译到表达式容器
		exprtk::parser<float> parser;
		if (!parser.compile(ui->expression->text().toStdString(), expr))
		{
			QMessageBox::warning(this, "警告", "输入的公式无效");
			return;
		}

		// 保存计算结果
		// m_expressionResults[m_selectedItem.first] = expr.value();

		// 修改expression
        expression->SetExpression(ui->expression->text(), associatedFeatures, expr.value());
        ui->expressionWidget->item(m_selectedItem.first, 1)->setText(ui->expression->text());
		ui->expressionWidget->item(m_selectedItem.first, 2)->setText(QString::number(expr.value()));

		m_expressionManager->ApplyExpression(expression);
	}
}

void QRSExpressionWidget::onAddExpression()
{
	auto rowCount = ui->expressionWidget->rowCount();
	ui->expressionWidget->insertRow(rowCount);
	m_expressions[rowCount] = m_expressionManager->AddCustomExpression();
	ui->expressionWidget->setItem(rowCount, 0, new QTableWidgetItem(QString("")));
	ui->expressionWidget->setItem(rowCount, 1, new QTableWidgetItem(QString("")));
	ui->expressionWidget->setItem(rowCount, 2, new QTableWidgetItem(QString("")));
	ui->expressionWidget->setItem(rowCount, 3, new QTableWidgetItem(QString("custom expression")));

	ui->expressionWidget->selectRow(rowCount);
	onTableWidgetItemClicked(ui->expressionWidget->item(rowCount, 0));
}

void QRSExpressionWidget::onDeleteExpression()
{
	if (m_selectedItem.first >= 0)
	{
		// 暂时隐藏这一行
		ui->expressionWidget->setRowHidden(m_selectedItem.first, true);
		m_deleteExpressionIndex.push_back(m_selectedItem.first);
	}
}
